/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



// Bomb launcher

//# address-hook(0x03c462) end(0x03c520)
function void fn03c462()
{
	objA0.mapping_offset = 0x03c78e
	objA0.sprite_attributes = (sprite_attribute.PRIORITY | sprite_attribute.PALETTE.LINE1 | 0x032b)
	objA0.render_flags |= render_flag.WORLD
	objA0.box_size.x = 0x10
	objA0.box_size.y = 0x10
	objA0.sprite_priority = 0x80

	u16[A0 + 0x30] = ((objA0.subtype2c & 0x0c) + 4) * 4
	D0.u8 = objA0.subtype2c & 0x03
	u8[A0 + 0x34] = D0.u8
	u8[A0 + 0x35] = D0.u8
	D1.u8 = objA0.subtype2c & 0x70
	u8[A0 + 0x32] = D1.u8
	if (s8[A0 + 0x2c] < 0)
	{
		if (allocDynamicObjectAfterA0())
		{
			objA1.update_address = 0x03c636
			objA1.position.x.u16 = objA0.position.x.u16
			objA1.position.y.u16 = objA0.position.y.u16
			objA1.position.x.u16 += 0x30
			objA1.position.y.u16 -= 0x30
			u16[A1 + 0x44] = objA0.position.x.u16
			objA1.render_flags = objA0.render_flags
			objA1.mapping_offset = objA0.mapping_offset
			objA1.sprite_attributes = (sprite_attribute.PRIORITY | sprite_attribute.PALETTE.LINE2 | 0x032b)
			objA1.sprite_priority = 0x0100
			objA1.box_size.x = 0x20
			objA1.box_size.y = 0x08
			u8[A1 + 0x22] = 0x06
			u8[A1 + 0x2a] |= 0x80
			u16[A1 + 0x3c] = A0.u16
		}
		u8[A0 + 0x40] = 0x05
	}

	objA0.update_address = 0x03c526
	fn03c526()
}


//# address-hook(0x03c526) end(0x03c52e)
function void fn03c526()
{
	if (s8[A0 + 0x04] >= 0)
	{
		DrawOrUnloadObject()
	}
	else
	{
		objA0.update_address = 0x03c534
		fn03c534()
	}
}


//# address-hook(0x03c534) end(0x03c54c)
function void fn03c534()
{
	D0.u8 = level.framecounter.low + u8[A0 + 0x32]
	if (D0.u8 != 0)
	{
		DrawOrUnloadObject()
	}
	else
	{
		objA0.countdown_value = 0
		objA0.animation.sprite = 1
		objA0.update_address = 0x03c552
		fn03c552()
	}
}


//# address-hook(0x03c552) end(0x03c60c)
function void fn03c552()
{
	--objA0.countdown_value
	if (objA0.countdown_value < 0)
	{
		objA0.countdown_value = u16[A0 + 0x30]
		if (allocDynamicObjectAfterA0())
		{
			objA1.update_address = 0x03c6cc
			objA1.position.x.u16 = objA0.position.x.u16
			objA1.position.y.u16 = objA0.position.y.u16
			objA1.position.y.u16 -= 0x04
			u16[A1 + 0x46] = objA0.position.y.u16
			u16[A1 + 0x46] -= 0x44
			objA1.render_flags = objA0.render_flags
			objA1.mapping_offset = objA0.mapping_offset
			objA1.sprite_attributes = (sprite_attribute.PRIORITY | sprite_attribute.PALETTE.LINE1 | 0x032b)
			objA1.sprite_priority = 0x80
			objA1.box_size.x = 0x08
			objA1.box_size.y = 0x24
			u8[A1 + 0x1e] = 0x0c
			u8[A1 + 0x22] = 0x02
			objA1.velocity.y = -0x600
			objA1.position.y.u16 += 0x06
			u8[A1 + 0x2c] = objA0.subtype2c
			u16[A1 + 0x3c] = A0.u16

			D0.u16 = objA0.animation.frame & 0x0e
			D0 = u16[0x03c612 + D0.u16]
			u32[A1 + 0x36] = D0 << 8

			objA0.animation.frame += 2
			playSound(0x67)
		}

		--u8[A0 + 0x34]
		if (s8[A0 + 0x34] < 0)
		{
			u8[A0 + 0x34] = u8[A0 + 0x35]
			objA0.update_address = 0x03c622
			objA0.animation.timer = 7
		}
	}

	DrawOrUnloadObject()
}


//# address-hook(0x03c622) end(0x03c634)
function void fn03c622()
{
	--objA0.animation.timer
	if (s8(objA0.animation.timer) < 0)
	{
		objA0.animation.sprite = 0
		objA0.update_address = 0x03c534
	}
	DrawOrUnloadObject()
}



// Part of the floor get gets destroyed (and opened) by the bombs

//# address-hook(0x03c636) end(0x03c6b6)
function void fn03c636()
{
	A1 = 0xffff0000 + u16[A0 + 0x3c]
#if STANDALONE
	// Limit number of bombs neede to 2 instead of the usual 5
	u8[A1 + 0x40] = min(u8[A1 + 0x40], 2)
#endif
	if (u8[A1 + 0x40] == 0)
	{
		A2 = 0x03c6bc
		D1 = 3
		while (D1.s16 >= 0)
		{
			if (allocDynamicObjectAfterA0())
			{
				objA1.update_address = addressof(SmallExplosion.BaseUpdate)
				u8[A1 + 0x05] = 0x06
				objA1.sprite_attributes = sprite_attribute.PRIORITY
				objA1.position.x.u16 = objA0.position.x.u16
				objA1.position.y.u16 = objA0.position.y.u16
				D0.u16 = u16[(A2+=2)-2]
				objA1.position.x.u16 += D0.u16
				D0.u16 = u16[(A2+=2)-2]
				objA1.position.y.u16 += D0.u16
			}
			--D1.s16
		}

		objA0.position.x.u16 = 0x7f00
		u16[A0 + 0x44] = objA0.position.x.u16
		playSound(0x81)
	}

	D1 = objA0.box_size.x + 11
	D2 = objA0.box_size.y
	D3.u16 = D2.u16 + 1
	D4.u16 = objA0.position.x.u16
	fn01dc56()

	D0.u16 = u16[A0 + 0x44]
	DrawOrUnloadObjectByD0()
}



// The parachute bomb itself

//# address-hook(0x03c6cc) end(0x03c75c)
function void fn03c6cc()
{
	UpdateMovementStraightSimple()
	if (objA0.velocity.y < 0)
	{
		objA0.velocity.y += 0x18
		if (objA0.velocity.y >= 0)
		{
			objA0.animation.sprite = 0x03
			objA0.collision_attributes = (collision.flag.THREAT | collision.size.4x8)
			objA0.sprite_attributes &= ~sprite_attribute.PRIORITY
		}
	}
	else
	{
		bool goto03c740 = false
		objA0.velocity.y += 0x10
		if (s8[A0 + 0x2c] >= 0)
		{
			goto03c740 = true
		}
		else
		{
			A1 = 0xffff0000 + u16[A0 + 0x3c]
			if (u8[A1 + 0x40] == 0)
			{
				goto03c740 = true
			}
			else if (u16[A0 + 0x46] < objA0.position.y.u16)
			{
				objA0.position.y.u16 = u16[A0 + 0x46]
				objA0.update_address = 0x03c768
				--u8[A1 + 0x40]
				if (u8[A1 + 0x40] == 0)
				{
					u8[A1 + 0x2c] &= 0x7f
				}
			}
		}

		if (goto03c740)
		{
			CheckGroundCollision()
			if (D1.s16 < 0)
			{
				objA0.position.y.u16 += D1.u16
				objA0.update_address = 0x03c768
			}
		}
	}

	D0.u16 = abs(objA0.velocity.y)
	if (D0.u16 < 0x01d0)
	{
		D0 = u32[A0 + 0x36]
		objA0.position.x += D0
	}

	AddAsDynamicObject()
	DrawObject()
}



// Bomb explosion

//# address-hook(0x03c768) end(0x03c788)
function void fn03c768()
{
	objA0.position.y.u16 += 4
	objA0.update_address = addressof(SmallExplosion.BaseUpdate)
	objA0.base_state = 0x06
	u8[A0 + 0x28] = 0
	u8[A0 + 0x29] = 0

	playSound(0xb4)
	SmallExplosion.BaseUpdate()
}
